<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>SoundManager 2: Basic Video Template</title>
<style type="text/css">

body {
 background:#fff;
 overflow:hidden;
}

#soundmanager-debug {
 /* SM2 debug container (optional, use or customize this as you like - makes in-browser debug output more useable) */
 position:fixed;_position:absolute;right:1em;bottom:1em;width:50em;height:18em;overflow:auto;background:#fff;margin:1em;padding:1em;border:1px solid #999;font-family:monaco,"lucida console",verdana,tahoma,"sans serif";font-size:x-small;line-height:1.5em;opacity:0.9;filter:alpha(opacity=90);
}

#lights {
 position:absolute;
 left:0px;
 top:0px;
 width:100%;
 height:100%;
 overflow:hidden;
 display:none;
 z-index:2;
}

.xlsf-light {
 position:absolute;
 margin-top:-1px;
}

body.fast .xlsf-light {
 opacity:0.9;
}

.xlsf-light {
 opacity:0.9;
}

.xlsf-fragment {
 position:absolute;
 background:transparent url(../christmas-lights/image/bulbs-50x50-fragments.png) no-repeat 0px 0px;
 width:50px;
 height:50px;
}

.xlsf-fragment-box {
 position:absolute;
 left:0px;
 top:0px;
 width:50px;
 height:50px;
 *width:100%;
 *height:100%;
 display:none;
}

.xlsf-cover {
 position:fixed;
 left:0px;
 top:0px;
 width:100%;
 height:100%;
 background:#fff;
 opacity:1;
 z-index:999;
 display:none;
}

</style>
<!-- some CSS for this demo page, not required for SM2 -->
<link rel="stylesheet" href="template.css" />
<style type="text/css">

#theworld h1,
#theworld p {
 text-shadow:1px 1px 2px #336699;
}

</style>
<!-- include SM2 library -->
<script type="text/javascript" src="../../script/soundmanager2.js"></script>

<!-- And now, customize it! -->
<script type="text/javascript">

/*
   DHTML PNG Snowstorm! OO-style Jascript-based Snow effect
   --------------------------------------------------------
   Version 1.3.20081215 (Previous rev: v1.2.20041121a)
   Dependencies: GIF/PNG images (0 through 4.gif/png)
   Code by Scott Schiller - http://schillmania.com
   --------------------------------------------------------
   Description:
  
   Initializes after body onload() by default (via addEventHandler() call at bottom.)
  
   Properties:
  
   usePNG
   ---------------
   Enables PNG images if supported ("false" falls back to GIF)
  
   flakeTypes
   ---------------
   Sets the range of flake images to use (eg. a value of 5
   will use images ranging from 0.png to 4.png.)
  
   flakesMax
   ---------------
   Sets the maximum number of snowflakes that can exist on
   the screen at any given time.
   
   flakesMaxActive
   ---------------
   Sets the limit of "falling" snowflakes (ie. moving, thus
   considered to be "active".)
  
   vMax
   ---------------
   Defines the maximum X and Y velocities for the storm.
   A range up to this value is selected at random.
  
   flakeWidth
   ---------------
   The width (in pixels) of each snowflake image.
  
   flakeHeight
   ---------------
   Height (pixels) of each snowflake image.
   
   flakeBottom
   ---------------
   Limits the "bottom" coordinate of the snow.

   snowStick
   ---------------
   Allows the snow to "stick" to the bottom of the window.
   When off, snow will never sit at the bottom.
  
   snowCollect
   ---------------
   Enables snow to pile up (slowly) at bottom of window.
   Can be very CPU/resource-intensive over time.
   Also requires snowStick = true.

   followMouse
   ---------------
   Allow the mouse to affect the "wind", left-to-right.

*/

var snowStorm = null;

function SnowStorm() {

  // PROPERTIES
  // ------------------

  var imagePath = 'http://www.schillmania.com/projects/snowstorm/image/snow/'; // relative path to snow images (including trailing slash)
  var flakesMax = 128;
  var flakesMaxActive = 64;
  var vMaxX = 8;
  var vMaxY = 4;
  var usePNG = true;
  var flakeBottom = null;        // Integer for fixed bottom, 0 or null for "full-screen" snow effect
  var snowStick = true;
  var snowCollect = false;
  var targetElement = null;      // element which snow will be appended to (document body if undefined)
  var followMouse = true;
  var flakeTypes = 6;
  var flakeWidth = 5;
  var flakeHeight = 5;

  // ------------------

  var zIndex = 5; // CSS stacking order applied to each snowflake
  var flakeLeftOffset = 0; // amount to subtract from edges of container
  var flakeRightOffset = 0; // amount to subtract from edges of container

  // --- End of user section ---

  var addEvent = function(o,evtName,evtHandler) {
    typeof(attachEvent)=='undefined'?o.addEventListener(evtName,evtHandler,false):o.attachEvent('on'+evtName,evtHandler);
  }

  var removeEvent = function(o,evtName,evtHandler) {
    typeof(attachEvent)=='undefined'?o.removeEventListener(evtName,evtHandler,false):o.detachEvent('on'+evtName,evtHandler);
  }

  var classContains = function(o,cStr) {
    return (typeof(o.className)!='undefined'?o.className.indexOf(cStr)+1:false);
  }

  var s = this;
  var storm = this;
  this.timers = [];
  this.flakes = [];
  this.disabled = false;
  this.terrain = [];
  this.active = false;

  var isIE = navigator.userAgent.match(/msie/i);
  var isIE6 = navigator.userAgent.match(/msie 6/i);
  var isOldIE = (isIE && (isIE6 || navigator.userAgent.match(/msie 5/i)));
  var isWin9X = navigator.appVersion.match(/windows 98/i);
  var isiPhone = navigator.userAgent.match(/iphone/i);
  var isBackCompatIE = (isIE && document.compatMode == 'BackCompat');
  var isOpera = navigator.userAgent.match(/opera/i);
  if (isOpera) isIE = false; // Opera (which may be sneaky, pretending to be IE by default)
  var noFixed = (isBackCompatIE || isIE6 || isiPhone);
  var screenX = null;
  var screenX2 = null;
  var screenY = null;
  var scrollY = null;
  var vRndX = null;
  var vRndY = null;
  var windOffset = 1;
  var windMultiplier = 2;
  var pngSupported = (!isIE || (isIE && !isIE6 && !isOldIE)); // IE <7 doesn't do PNG nicely without crap filters
  var docFrag = document.createDocumentFragment();
  this.oControl = null; // toggle element
  if (flakeLeftOffset == null) flakeLeftOffset = 0;
  if (flakeRightOffset == null) flakeRightOffset = 0;

  function rnd(n,min) {
    if (isNaN(min)) min = 0;
    return (Math.random()*n)+min;
  }

  this.randomizeWind = function() {
    vRndX = plusMinus(rnd(vMaxX,0.2));
    vRndY = rnd(vMaxY,0.2);
    if (this.flakes) {
      for (var i=0; i<this.flakes.length; i++) {
        if (this.flakes[i].active) this.flakes[i].setVelocities();
      }
    }
  }

  function plusMinus(n) {
    return (parseInt(rnd(2))==1?n*-1:n);
  }

  this.scrollHandler = function() {
    // "attach" snowflakes to bottom of window if no absolute bottom value was given
    scrollY = (flakeBottom?0:parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop));
    if (isNaN(scrollY)) scrollY = 0; // Netscape 6 scroll fix
    if (!flakeBottom && s.flakes) {
      for (var i=0; i<s.flakes.length; i++) {
        if (s.flakes[i].active == 0) s.flakes[i].stick();
      }
    }
  }

  this.resizeHandler = function() {
    if (window.innerWidth || window.innerHeight) {
      screenX = window.innerWidth-(!isIE?16:2)-flakeRightOffset;
      screenY = (flakeBottom?flakeBottom:window.innerHeight);
    } else {
      screenX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth)-(!isIE?8:0)-flakeRightOffset;
      screenY = flakeBottom?flakeBottom:(document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
    }
    screenX2 = parseInt(screenX/2);
  }

  this.resizeHandlerAlt = function() {
    screenX = targetElement.offsetLeft+targetElement.offsetWidth-flakeRightOffset;
    screenY = flakeBottom?flakeBottom:targetElement.offsetTop+targetElement.offsetHeight;
    screenX2 = parseInt(screenX/2);
  }

  this.freeze = function() {
    // pause animation
    if (!s.disabled) {
      s.disabled = 1;
    } else {
      return false;
    }
    for (var i=0; i<s.timers.length; i++) {
      clearInterval(s.timers[i]);
    }
  }

  this.resume = function() {
    if (s.disabled) {
       s.disabled = 0;
    } else {
      return false;
    }
    s.timerInit();
  }

  this.toggleSnow = function() {
    if (!s.flakes.length) {
      // first run
      s.start();
      s.setControlActive(true);
    } else {
      s.active = !s.active;
      if (s.active) {
        s.show();
        s.resume();
        s.setControlActive(true);
      } else {
        s.stop();
        s.freeze();
        s.setControlActive(false);
      }
    }
  }

  this.stop = function() {
    this.freeze();
    for (var i=this.flakes.length; i--;) {
      this.flakes[i].o.style.display = 'none';
    }
    removeEvent(window,'scroll',s.scrollHandler);
    removeEvent(window,'resize',s.resizeHandler);
    if (!isIE) {
      removeEvent(window,'blur',s.freeze);
      removeEvent(window,'focus',s.resume);
    }
    // removeEventHandler(window,'resize',this.resizeHandler,false);
  }

  this.show = function() {
    for (var i=this.flakes.length; i--;) {
      this.flakes[i].o.style.display = 'block';
    }
  }

  this.SnowFlake = function(parent,type,x,y) {
    var s = this;
    var storm = parent;
    this.type = type;
    this.x = x||parseInt(rnd(screenX-20));
    this.y = (!isNaN(y)?y:-rnd(screenY)-12);
    this.vX = null;
    this.vY = null;
    this.vAmpTypes = [2.0,1.0,1.25,1.0,1.5,1.75]; // "amplification" for vX/vY (based on flake size/type)
    this.vAmp = this.vAmpTypes[this.type];

    this.active = 1;
    this.o = document.createElement('img');
    this.o.style.position = 'absolute';
    this.o.style.width = flakeWidth+'px';
    this.o.style.height = flakeHeight+'px';
    this.o.style.fontSize = '1px'; // so IE keeps proper size
    this.o.style.zIndex = zIndex;
    this.o.src = imagePath+this.type+(pngSupported && usePNG?'.png':'.gif');
    docFrag.appendChild(this.o);

    this.refresh = function() {
      s.o.style.left = s.x+'px';
      s.o.style.top = s.y+'px';
    }

    this.stick = function() {
      if (noFixed || (targetElement != document.documentElement && targetElement != document.body)) {
	s.o.style.top = (screenY+scrollY-flakeHeight-storm.terrain[Math.floor(s.x)])+'px';
      } else {
        s.o.style.display = 'none';
	s.o.style.top = 'auto';
        s.o.style.bottom = '0px';
	s.o.style.position = 'fixed';
        s.o.style.display = 'block';
      }
    }

    this.vCheck = function() {
      if (s.vX>=0 && s.vX<0.2) {
        s.vX = 0.2;
      } else if (s.vX<0 && s.vX>-0.2) {
        s.vX = -0.2;
      }
      if (s.vY>=0 && s.vY<0.2) {
        s.vY = 0.2;
      }
    }

    this.move = function() {
      var vX = s.vX*windOffset;
      s.x += vX;
      s.y += (s.vY*s.vAmp);
      if (vX >= 0 && (s.x >= screenX || screenX-s.x < (flakeWidth+1))) { // X-axis scroll check
        s.x = 0;
      } else if (vX < 0 && s.x-flakeLeftOffset<0-flakeWidth) {
        s.x = screenX-flakeWidth-1; // flakeWidth;
      }
      s.refresh();
      var yDiff = screenY+scrollY-s.y-storm.terrain[Math.floor(s.x)];
      if (yDiff<flakeHeight) {
        s.active = 0;
        if (snowCollect && snowStick) {
          var height = [0.75,1.5,0.75];
          for (var i=0; i<2; i++) {
            storm.terrain[Math.floor(s.x)+i+2] += height[i];
          }
        }
        s.o.style.left = (s.x/screenX*100)+'%'; // set "relative" left (change with resize)
        if (!flakeBottom) {
	  if (snowStick) {
            s.stick();
	  } else {
	    s.recycle();
	  }
        }
      }

    }

    this.animate = function() {
      // main animation loop
      // move, check status, die etc.
      s.move();
    }

    this.setVelocities = function() {
      s.vX = vRndX+rnd(vMaxX*0.12,0.1);
      s.vY = vRndY+rnd(vMaxY*0.12,0.1);
    }

    this.recycle = function() {
      s.o.style.display = 'none';
      s.o.style.position = 'absolute';
      s.o.style.bottom = 'auto';
      s.setVelocities();
      s.vCheck();
      s.x = parseInt(rnd(screenX-flakeWidth-20));
      s.y = parseInt(rnd(screenY)*-1)-flakeHeight;
      s.o.style.left = s.x+'px';
      s.o.style.top = s.y+'px';
      s.o.style.display = 'block';
      s.active = 1;
    }

    this.recycle(); // set up x/y coords etc.
    this.refresh();

  }

  this.snow = function() {
    var active = 0;
    var used = 0;
    var waiting = 0;
    for (var i=s.flakes.length; i--;) {
      if (s.flakes[i].active == 1) {
        s.flakes[i].move();
        active++;
      } else if (s.flakes[i].active == 0) {
        used++;
      } else {
        waiting++;
      }
    }
    if (snowCollect && !waiting) { // !active && !waiting
      // create another batch of snow
      s.createSnow(flakesMaxActive,true);
    }
    if (active<flakesMaxActive) {
      with (s.flakes[parseInt(rnd(s.flakes.length))]) {
        if (!snowCollect && active == 0) {
          recycle();
        } else if (active == -1) {
          active = 1;
        }
      }
    }
  }

  this.mouseMove = function(e) {
    if (!followMouse) return true;
    var x = parseInt(e.clientX);
    if (x<screenX2) {
      windOffset = -windMultiplier+(x/screenX2*windMultiplier);
    } else {
      x -= screenX2;
      windOffset = (x/screenX2)*windMultiplier;
    }
  }

  this.createSnow = function(limit,allowInactive) {
    for (var i=0; i<limit; i++) {
      s.flakes[s.flakes.length] = new s.SnowFlake(s,parseInt(rnd(flakeTypes)));
      if (allowInactive || i>flakesMaxActive) s.flakes[s.flakes.length-1].active = -1;
    }
    targetElement.appendChild(docFrag);
  }

  this.timerInit = function() {
    s.timers = (!isWin9X?[setInterval(s.snow,20)]:[setInterval(s.snow,75),setInterval(s.snow,25)]);
  }

  this.init = function() {
    for (var i=0; i<2048; i++) {
      s.terrain[i] = 0;
    }
    s.randomizeWind();
    s.createSnow(snowCollect?flakesMaxActive:flakesMaxActive*2); // create initial batch
    addEvent(window,'resize',s.resizeHandler);
    addEvent(window,'scroll',s.scrollHandler);
    if (!isIE) {
      addEvent(window,'blur',s.freeze);
      addEvent(window,'focus',s.resume);
    }
    s.resizeHandler();
    s.scrollHandler();
    if (followMouse) {
      addEvent(document,'mousemove',s.mouseMove);
    }
    s.timerInit();
  }

  var didInit = false;

  this.start = function(bFromOnLoad) {
	if (!didInit) {
	  didInit = true;
	} else if (bFromOnLoad) {
	  // already loaded and running
	  return true;
	}
    if (typeof targetElement == 'string') {
      targetElement = document.getElementById(targetElement);
      if (!targetElement) throw new Error('Snowstorm: Unable to get targetElement');
    }
	if (!targetElement) {
	  targetElement = (!isIE?(document.documentElement?document.documentElement:document.body):document.body);
	}
    if (targetElement != document.documentElement && targetElement != document.body) s.resizeHandler = s.resizeHandlerAlt; // re-map handler to get element instead of screen dimensions
    s.resizeHandler(); // get bounding box elements
    if (screenX && screenY && !s.disabled) {
      s.init();
      s.active = true;
    }
  }

  if (document.addEventListener) {
	// safari 3.0.4 doesn't do DOMContentLoaded, maybe others - use a fallback to be safe.
	document.addEventListener('DOMContentLoaded',function(){s.start(true)},false);
    window.addEventListener('load',function(){s.start(true)},false);
  } else {
    addEvent(window,'load',function(){s.start(true)});
  }

}

if (window.location.href.toString().match(/snow/i)) {
  snowStorm = new SnowStorm();
}

// soundManager.debugMode = false; // disable debug output

var isFun = true; // for xmaslights-home.js tweaks

soundManager.url = '../../swf/'; // path to directory containing SoundManager2 .SWF file
soundManager.flashVersion = 9; // flash 9.0r115+ required for MovieStar mode
soundManager.useMovieStar = true; // enable AAC/MPEG4 video in SM2
soundManager.useHighPerformance = true;
soundManager.useFastPolling = true;
soundManager.wmode = 'transparent';

if (window.location.toString().match(/debug/i)) {
  soundManager.debugMode = true;
} else {
  soundManager.debugMode = false;
}

soundManager.onload = function() {
  // soundManager.createSound() etc. may now be called

  if (!window.location.href.toString().match(/snow/i)) {
	$('withSnow').style.display = 'block';
  }

  doChristmasLights();

  var keyTiming = [];
  var keyActions = [];

  function addAction(oTime,oFunction) {
    keyTiming.push(oTime);
    keyActions.push(oFunction);	
  }

  function addPoke(nTime,duration,scale) {
    if (typeof scale == 'undefined') {
	  scale = 1;
    }
    addAction(
	  nTime,
	  function() {
	    poke(duration,scale);
	  }
	);
	addAction(nTime, function() {
	  for (var i=1+parseInt(Math.random()*5); i--;) {
	    xlsf.lights[parseInt(Math.random()*xlsf.lights.length)].smash();
	  }
	});
  }

  addPoke(8000,5);
  addPoke(9650,5);
  addPoke(10200,5);
  addPoke(10900,5);
  addPoke(12400,5);
  addPoke(14150,5);
  addPoke(16750,5);
  addPoke(17380,5);

  addPoke(19000,10,0.25);
  addPoke(19200,10,0.5);
  addPoke(19400,10,0.75);
  addPoke(19600,10,1);
  addPoke(19800,10,1.25);
  addPoke(20000,20,1);
  addAction(20000,function() {
    xlsf.uberSmash();
  });
  addPoke(20400,20,0.75);
  addPoke(20600,10,0.5);
  addPoke(20800,5,0.25);

  var keyFired = 0;
  var keyLength = keyTiming.length;

  soundManager.createVideo({
	id:'wall',
	url:'http://freshly-ground.com/data/video/wall-240x180.mp4',
	whileplaying:function() {
	  // check time and key points
      if (keyFired < keyLength && this.position >= keyTiming[keyFired]) {
		keyActions[keyFired]();
		keyFired++;
		// check others also
		this.whileplaying();
	  }
	},
	onmetadata:function() {
	  soundManager._writeDebug('start');
	}
  });
  soundManager.play('wall');
}

function poke(nDuration,scale) {
  var o = document.getElementById('theworld');
  var o2 = document.getElementById('lights');
  // o.style.overflow = 'hidden';
  var i = nDuration;
  if (typeof scale == 'undefined') {
    scale = 1;	
  }
  function shake() {
	var rnd = (parseInt(Math.random()*8*scale*(Math.random()>0.5?1:-1)));
	var rnd2 = (parseInt(Math.random()*8*scale/2*(Math.random()>0.5?1:-1)));
	o.style.marginLeft = rnd+'px';
	o.style.marginTop = rnd2+'px';
	o2.style.marginLeft = parseInt(rnd2/2)+'px';
	o2.style.marginTop = (Math.abs(rnd2)*-1)+'px';
	if (i <= 0) {
	  o.style.marginLeft = '0px';
	  o.style.marginTop = '0px';
	  o2.style.marginLeft = '0px';
	  o2.style.marginTop = '0px';
	  window.clearTimeout(t);
	}
	i--;
  }
  var t = window.setInterval(shake,20);
}

function changeFontSize(nDuration,scale) {
  var o = document.getElementById('theworld');
  var oS = o.getElementsByTagName('h1')[0].getElementsByTagName('span');
  var i = nDuration;
  if (typeof scale == 'undefined') {
    scale = 1;	
  }
  var rnd = 100;
  var scaleBase = 50;
  function change() {
	var newSize = null;
	var sineSpan = 16;
	for (var j=oS.length; j--;) {
	  oS[j].style.fontSize = 100+(50*Math.sin(Math.PI/2*((j+i)/sineSpan)))+'%';
	}
	i--;
	if (i <= 0) {
	  for (j=oS.length; j--;) {
	    oS[j].style.fontSize = '100%';
	  }
	  window.clearTimeout(t);
	}
  }
  var t = window.setInterval(change,20);
}

setTimeout(function(){

// changeFontSize(100,10);

},500);

function loadScript(sURL,onLoad) {
  var loadScriptHandler = function() {
    var rs = this.readyState;
    if (rs == 'loaded' || rs == 'complete') {
      this.onreadystatechange = null;
      this.onload = null;
      window.setTimeout(onLoad,20);
	}
  }
  function scriptOnload() {
    this.onreadystatechange = null;
    this.onload = null;
    window.setTimeout(onLoad,20);
  }
  var oS = document.createElement('script');
  oS.type = 'text/javascript';
  if (onLoad) {
    oS.onreadystatechange = loadScriptHandler;
    oS.onload = scriptOnload;
  }
  oS.src = sURL;
  document.getElementsByTagName('head')[0].appendChild(oS);
}

function doChristmasLights() {
  var o = document.getElementsByTagName('h1')[0];
  loadScript('http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/animation/animation-min.js',function(){
    loadScript('../christmas-lights/christmaslights-home.js',function(){
    if (typeof smashInit != 'undefined') {
      setTimeout(function() {
	    o.style.display = 'none';
	    smashInit('../christmas-lights/','pico');
	    o.style.display = 'block';
	  },20);
    }
    });
  });
}

function $(sID) {
  return document.getElementById(sID);
}


</script>

<!-- SM2 BAREBONES TEMPLATE: END -->

</head>

<body>

<div id="shade" style="position:absolute;left:0px;bottom:240px;width:100%;height:100%;background:#56bafc url(56bafc-gradient.jpg) bottom left repeat-x"></div>

<div id="lights"></div>

<div id="theworld" style="position:absolute;z-index:2;padding-left:24px;padding-top:12px">

 <h1 style="color:#fff">SoundManager 2: Video + Audio Fun</h1>
 <p style="width:54em;color:#fff">This is a hacked-together example of video and JS-triggered events, based on a simple timeline using whileplaying() and the position property of a SM2 sound object.</p>

<p id="withSnow" style="display:none;z-index:99"><a href="#snow=1" onclick="window.location.replace(this.href);window.location.reload()" style="color:#fff">With snow</a></p>

</div>

<!-- sm2-container can be resized via JS to fit movie, or via CSS -->
<div id="sm2-container" style="position:fixed;_position:absolute;width:180px;height:240px;bottom:0px;left:0px"><!-- flash movie will go here --></div>

</body>
</html>
